package com.cheetah.start.common.shoesImg;

import org.opencv.core.*;
import org.opencv.imgproc.Imgproc;

import java.util.Arrays;

public class UniversalShoeComparison {

    /**
     * 通用鞋子对比方法 - 自动处理任何背景
     */
    public static double compareShoesUniversal(Mat image1, Mat image2) {
        System.out.println("开始通用鞋子对比...");

        // 1. 特征点匹配相似度
        double featureSimilarity = FeatureBasedComparison.compareBySalientFeatures(image1, image2);
        System.out.println("特征点相似度: " + featureSimilarity);


        // 3. 背景去除后的直方图相似度
        Mat noBg1 = UniversalBackgroundRemoval.removeAnyBackground(image1);
        Mat noBg2 = UniversalBackgroundRemoval.removeAnyBackground(image2);
        double histSimilarity = compareHistograms(noBg1, noBg2);
        System.out.println("直方图相似度: " + histSimilarity);

        // 加权综合评分
        double finalScore = featureSimilarity * 0.4  + histSimilarity * 0.2;

        System.out.println("最终相似度: " + finalScore);
        return finalScore;
    }

    private static double compareHistograms(Mat image1, Mat image2) {
        Mat hsv1 = new Mat(), hsv2 = new Mat();
        Imgproc.cvtColor(image1, hsv1, Imgproc.COLOR_BGR2HSV);
        Imgproc.cvtColor(image2, hsv2, Imgproc.COLOR_BGR2HSV);

        // 创建掩码只计算非黑色区域
        Mat mask1 = createForegroundMask(image1);
        Mat mask2 = createForegroundMask(image2);

        Mat hist1 = new Mat(), hist2 = new Mat();
        Imgproc.calcHist(Arrays.asList(hsv1), new MatOfInt(0, 1), mask1,
                hist1, new MatOfInt(18, 12), new MatOfFloat(0, 180, 0, 256));
        Imgproc.calcHist(Arrays.asList(hsv2), new MatOfInt(0, 1), mask2,
                hist2, new MatOfInt(18, 12), new MatOfFloat(0, 180, 0, 256));

        Core.normalize(hist1, hist1, 1, 0, Core.NORM_L2);
        Core.normalize(hist2, hist2, 1, 0, Core.NORM_L2);

        return Imgproc.compareHist(hist1, hist2, Imgproc.CV_COMP_CORREL);
    }

    private static Mat createForegroundMask(Mat image) {
        Mat mask = new Mat();
        Core.inRange(image, new Scalar(1, 1, 1), new Scalar(255, 255, 255), mask);
        return mask;
    }

    private static double computeCosineSimilarity(Mat v1, Mat v2) {
        double dotProduct = v1.dot(v2);
        double norm1 = Core.norm(v1, Core.NORM_L2);
        double norm2 = Core.norm(v2, Core.NORM_L2);

        if (norm1 == 0 || norm2 == 0) {
            return 0;
        }
        return dotProduct / (norm1 * norm2);
    }
}
